package br.com.virtual.cadastrar.dao.impl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import br.com.virtual.base.dao.impl.BaseDaoImpl;
import br.com.virtual.cadastrar.dao.ProdutoDAO;
import br.com.virtual.cadastrar.model.Categoria;
import br.com.virtual.cadastrar.model.Grupo;
import br.com.virtual.cadastrar.model.Produto;

public class ProdutoDAOImpl extends BaseDaoImpl implements ProdutoDAO,
		Serializable {

	private static final long serialVersionUID = 1L;

	@Override
	public Produto create(Produto produto) {

		getManager().persist(produto);
		return produto;
	}

	@Override
	public Produto read(Long id) {
		return getManager().find(Produto.class, id);
	}

	@Override
	public void update(Produto produto) {
		getManager().merge(produto);
	}

	@Override
	public void delete(Produto produto) {
		getManager().remove(read(produto.getId()));
	}

	@Override
	public List<Produto> getList() {
		return this.list("", " order by p.id desc ");
	}

	@Override
	public List<Produto> getListAtivo() {
		return this.list(" where p.ativo = true ", " order by p.id desc ");
	}

	private List<Produto> list(String where, String order) {
		List<Produto> list = new ArrayList<Produto>(getManager().createQuery(
				"from Produto p " + where + order, Produto.class)
				.getResultList());

		return list;
	}

	@Override
	public List<Produto> getListDestaque() {
		return this.list(" where p.ativo = true and p.destaque = true ",
				" order by p.ordem, p.nome desc ");
	}

	@Override
	public List<Produto> getListBanner() {
		return this.list(" where p.ativo = true and p.banner = true ",
				" order by p.ordem, p.nome desc ");
	}

	@Override
	public List<Produto> findByNome(String nome) {

		List<Produto> list = new ArrayList<Produto>(
				getManager()
						.createQuery(
								"from Produto p where p.ativo = true and p.nome like :nome order by p.nome",
								Produto.class)
						.setParameter("nome", "%" + nome + "%").getResultList());

		return list;
	}

	@Override
	public List<Produto> getProdutosByCategoria(Categoria categoria) {

		List<Produto> lista;

		lista = new ArrayList<Produto>(
				this.getManager()
						.createQuery(
								"select p from Produto p"
										+ " left join p.categoria c"
										+ " where ( p.categoria = :categoria or c.pai = :categoria ) and p.ativo = true",
								Produto.class)
						.setParameter("categoria", categoria).getResultList());

		return lista;
	}

	@Override
	public List<Produto> getProdutosByGrupo(Grupo grupo) {

		List<Produto> lista;

		lista = new ArrayList<Produto>(this
				.getManager()
				.createQuery(
						"select p from Produto p" + " left join p.categoria c"
								+ " where c.grupo = :grupo and p.ativo = true",
						Produto.class).setParameter("grupo", grupo)
				.getResultList());

		return lista;
	}

	@Override
	public List<Produto> getListProdutoData() {

		// StringBuffer buffer = new StringBuffer("select p ");

		StringBuffer buffer = new StringBuffer("select new ");
		buffer.append(Produto.class.getName());
		buffer.append("( p.id, p.nome, p.fabricante, p.modelo, p.preco_venda, p.categoria) ");
		buffer.append(" from Produto p ");
		buffer.append(" where p.ativo = true ");

		List<Produto> produtos = new ArrayList<Produto>(getManager()
				.createQuery(buffer.toString(), Produto.class).getResultList());

		return produtos;
	}

	@Override
	public List<Produto> getListProdutoData(String query) {

		StringBuffer buffer = new StringBuffer("select new ");
		buffer.append(Produto.class.getName());
		buffer.append("( p.id, p.nome, p.fabricante, p.modelo, p.preco_venda, p.preco_venda_desconto, p.categoria) ");
		buffer.append(" from Produto p ");
		buffer.append(" where p.ativo = true and p.nome like :nome ");

		List<Produto> produtos = new ArrayList<Produto>(getManager()
				.createQuery(buffer.toString(), Produto.class)
				.setParameter("nome", "%" + query + "%").getResultList());

		return produtos;
	}

	@Override
	public void baixarEstoque(Produto produto, int quantidade) {

		produto = read(produto.getId());
		produto.setQuantidade(produto.getQuantidade() - quantidade);
		update(produto);
		
	}
}
